package com.summer.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.summer.content.dao.*;
import com.summer.commonException.XueChengException;
import com.summer.content.service.CourseBaseService;
import com.summer.dto.AddCourseDto;
import com.summer.dto.CourseBaseInfoDto;
import com.summer.dto.EditionDto;
import com.summer.dto.QueryCourseParamsDto;
import com.summer.model.PageParams;
import com.summer.model.PageResult;
import com.summer.pojo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Objects;

@Service
public class CourseBaseServiceImpl implements CourseBaseService {

    @Autowired
    private CourseBaseMapper courseBaseMapper;

    @Autowired
    private CourseMarketMapper courseMarketMapper;

    @Autowired
    private CourseCategoryMapper courseCategoryMapper;

    @Autowired
    private TeachPlanMapper teachPlanMapper;

    @Autowired
    private TeachplanMediaMapper teachplanMediaMapper;

    @Autowired
    private CourseTeacherMapper courseTeacherMapper;

    /**
     *
     * @param courseBaseNew 课程基本表信息
     * @param courseMarketNew 课程营销表信息
     * @return 组装返回CourseBaseInfoDto
     */
    private CourseBaseInfoDto getCourseBaseInfoDto(CourseBase courseBaseNew, CourseMarket courseMarketNew) {
        CourseBaseInfoDto courseBaseInfoDto = new CourseBaseInfoDto();
        BeanUtils.copyProperties(courseBaseNew, courseBaseInfoDto);
        BeanUtils.copyProperties(courseMarketNew, courseBaseInfoDto);

        CourseCategory courseCategoryBySt = courseCategoryMapper.selectById(courseBaseNew.getSt());
        courseBaseInfoDto.setStName(courseCategoryBySt.getName());
        CourseCategory courseCategoryByMt = courseCategoryMapper.selectById(courseBaseNew.getMt());
        courseBaseInfoDto.setMtName(courseCategoryByMt.getName());
        return courseBaseInfoDto;
    }

    @Override
    public PageResult<CourseBase> getByConditionAndPage(PageParams pageParams,
                                                        QueryCourseParamsDto queryCourseParamsDto,
                                                        String companyId) {
        // 分页构造器
        Page<CourseBase> page = new Page<>(pageParams.getPageNo(), pageParams.getPageSize());

        // 条件构造器
        String courseName = queryCourseParamsDto.getCourseName();
        String auditStatus = queryCourseParamsDto.getAuditStatus();
        String publishStatus = queryCourseParamsDto.getPublishStatus();

        LambdaQueryWrapper<CourseBase> lqw = new LambdaQueryWrapper<>();
        lqw.like(!StringUtils.isEmpty(courseName), CourseBase::getName, courseName);
        lqw.eq(!StringUtils.isEmpty(auditStatus), CourseBase::getAuditStatus, auditStatus);
        lqw.eq(!StringUtils.isEmpty(publishStatus), CourseBase::getStatus, publishStatus);
        // 数据权限控制：每个培训机构只能查到自己的课程
        lqw.eq(CourseBase::getCompanyId, companyId);

        Page<CourseBase> courseBasePage = courseBaseMapper.selectPage(page, lqw);

        // 封装返回结果
        PageResult<CourseBase> pageResult = new PageResult<>();
        pageResult.setPage(courseBasePage.getPages());
        pageResult.setItems(courseBasePage.getRecords());
        pageResult.setPageSize(courseBasePage.getSize());
        pageResult.setCounts(courseBasePage.getTotal());

        return pageResult;
    }


    @Override
    public CourseBaseInfoDto getBaseAndMarketInfo(Long id) {
        // 调用mapper查询base、market表
        CourseBase courseBase = courseBaseMapper.selectById(id);
        if (StringUtils.isEmpty(courseBase)){
            XueChengException.cast("id为: " + id +"的课程不存在!");
        }
        CourseMarket courseMarket = courseMarketMapper.selectById(id);
        if (StringUtils.isEmpty(courseMarket)){
            XueChengException.cast("id为: " + id +"的课程不存在!");
        }
        // 封装CourseBaseInfoDto返回
        return getCourseBaseInfoDto(courseBase, courseMarket);
    }

    // TODO : 1. throw RuntimeException及其子类不用在方法声明throws ... 抛出Exception或IOException才需要
    //        2. 如果发送了某个异常却没有处理，则程序会终止（服务器终止运行）
    @Transactional
    @Override
    public CourseBaseInfoDto addCourseBase(Long companyId, AddCourseDto dto) {
        // 1. 参数校验
        // 1.1 课程基本信息表的非空、逻辑校验
/*
        if (StringUtils.isEmpty(dto.getName())) {
            XueChengException.cast("课程名不能为空");
        }

        if (StringUtils.isEmpty(dto.getMt())) {
            XueChengException.cast("课程分类不能为空");
        }

        if (StringUtils.isEmpty(dto.getSt())) {
            XueChengException.cast("课程分类不能为空");
        }

        if (StringUtils.isEmpty(dto.getGrade())) {
            XueChengException.cast("课程等级为不能空");
        }

        if (StringUtils.isEmpty(dto.getTeachmode())) {
            XueChengException.cast("教育模式为不能空");
        }

        if (StringUtils.isEmpty(dto.getUsers())) {
            XueChengException.cast("适应人群为空");
        }

        // 1.2 课程营销表的非空、逻辑校验
        if (StringUtils.isEmpty(dto.getCharge())) {
            XueChengException.cast("收费规则为空");
        }
 */

        if(dto.getCharge().equals("201001")){
            if(dto.getPrice() == null || dto.getPrice() <=0){
                XueChengException.cast("课程为收费价格不能为空且必须大于0");
            }
        }
        // 2. 添加事务控制

        // 3. 添加course_base表

        //新增对象
        CourseBase courseBaseNew = new CourseBase();
        //将填写的课程信息赋值给新增对象
        BeanUtils.copyProperties(dto, courseBaseNew);
        //设置审核状态
        courseBaseNew.setAuditStatus("202002");
        //设置发布状态
        courseBaseNew.setStatus("203001");
        //机构id
        courseBaseNew.setCompanyId(companyId);
        //添加时间
        courseBaseNew.setCreateDate(LocalDateTime.now());
        //插入课程基本信息表
        int insert = courseBaseMapper.insert(courseBaseNew);
        if (insert <= 0) {
            XueChengException.cast("新增课程基本信息失败");
        }

        // TODO: 当某个表的某字段（如id）有逻辑上的外键约束时（数据库表没有实际绑定外键约束，但有外键的意义），
        //       添加数据时要根据外键字段查询表中是否有数据，有则修改没有则添加，防止有人操作数据库导致外键字段重复
        // 4. 添加course_market表
        //新增对象
        CourseMarket courseMarketNew = new CourseMarket();
        //将填写的课程信息赋值给新增对象
        BeanUtils.copyProperties(dto, courseMarketNew);
        //设置新增对象id，要放在深拷贝之后
        courseMarketNew.setId(courseBaseNew.getId());
        CourseMarket courseMarket = courseMarketMapper.selectById(courseBaseNew.getId());
        if (!StringUtils.isEmpty(courseMarket)){
            int i = courseMarketMapper.updateById(courseMarketNew);
            if (i <= 0){
                XueChengException.cast("更新课程营销信息失败");
            }
        }else {
            // 新增失败则抛出异常
            int i = courseMarketMapper.insert(courseMarketNew);
            if (i <= 0){
                XueChengException.cast("新增课程营销信息失败");
            }
        }

        // 5. 返回CourseInfoDto对象

        //  将新增的两个对象组装成CourseInfoDto对象返回

        return getCourseBaseInfoDto(courseBaseNew, courseMarketNew);

        // 注意代码中的空指针异常、其他逻辑异常
    }

    @Transactional
    @Override
    public CourseBaseInfoDto updateCourse(Long companyId, EditionDto dto) {
        // 1. 数据准备
        Long id = dto.getId();
        CourseBase courseBase = courseBaseMapper.selectById(id);
        if (StringUtils.isEmpty(courseBase)){
            XueChengException.cast("id为: " + id +"的课程不存在!");
        }
        CourseMarket courseMarket = courseMarketMapper.selectById(id);
        if (StringUtils.isEmpty(courseMarket)){
            XueChengException.cast("id为: " + id +"的课程不存在!");
        }

        // 2. 逻辑校验
        // 判断是否有权限修改: 课程创建公司才能修改
        if (!Objects.equals(courseBase.getCompanyId(), companyId)){
            XueChengException.cast("非课程创建者无权修改！");
        }
        // 价格字段的逻辑校验
        if(dto.getCharge().equals("201001")){
            if(dto.getPrice() == null || dto.getPrice() <=0){
                XueChengException.cast("课程为收费价格不能为空且必须大于0");
            }
        }

        // 3. 封装dto
        // 3.1 封装courseBase
        BeanUtils.copyProperties(dto, courseBase);
        courseBase.setChangeDate(LocalDateTime.now());
        courseBase.setChangePeople("xxx");

        // 3.2 封装courseMarket
        BeanUtils.copyProperties(dto, courseMarket);

        //4. 调用mapper修改
        int ib = courseBaseMapper.updateById(courseBase);
        if (ib <= 0){
            XueChengException.cast("修改课程失败");
        }
        int im = courseMarketMapper.updateById(courseMarket);
        if (im <= 0){
            XueChengException.cast("修改课程失败");
        }

        //5. 封装返回对象返回
        return getCourseBaseInfoDto(courseBase, courseMarket);
    }

    @Transactional
    @Override
    public void deleteCourse(Long id) {
        // 1. 数据准备
        CourseBase courseBase = courseBaseMapper.selectById(id);
        if (StringUtils.isEmpty(courseBase)){
            XueChengException.cast("课程不存在，删除课程失败");
        }

        // 2. 需求分析, 处理逻辑异常
        // 2.1 审核状态为未提交才能删除
        if(!courseBase.getAuditStatus().equals("202002")){
            XueChengException.cast("已提交的课程不能删除");
        }

        // 3. 调用mapper删除主表、关联表（事务处理）
        // 3.1 删除course_base
        int courseDelete = courseBaseMapper.deleteById(id);
        if (courseDelete <= 0){
            XueChengException.cast("删除失败,请重试");
        }
        // 3.2 删除course_market: delete from course_market where id = ?
        int marketDelete = courseMarketMapper.deleteById(id);
        if (marketDelete < 0){
            XueChengException.cast("删除课程营销信息失败");
        }

        // 3.3 删除teach_plan:    delete from teach_plan where course_id = ?
        LambdaQueryWrapper<Teachplan> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Teachplan::getCourseId, id);
        int planDelete = teachPlanMapper.delete(lqw);
        if (planDelete < 0){
            XueChengException.cast("删除课程计划失败");
        }

        // 3.4 删除teach_plan_media: delete from teach_plan_media where course_id = ?
        LambdaQueryWrapper<TeachplanMedia> lqw2 = new LambdaQueryWrapper<>();
        lqw2.eq(TeachplanMedia::getCourseId, id);
        int mediaDelete = teachplanMediaMapper.delete(lqw2);
        if (mediaDelete < 0){
            XueChengException.cast("删除课程媒资信息失败");
        }

        // 3.5 删除course_teach：delete from course_teacher where course_id = ?
        LambdaQueryWrapper<CourseTeacher> lqw3 = new LambdaQueryWrapper<>();
        lqw3.eq(CourseTeacher::getCourseId, id);
        int teacherDelete = courseTeacherMapper.delete(lqw3);
        if (teacherDelete < 0){
            XueChengException.cast("删除课程-教师关联信息失败");
        }
    }
}
